import os
import sys
import subprocess
import getopt
from datetime import datetime


CLIENT_HOME = os.path.abspath(os.path.dirname(sys.argv[0]))
CLIENT_WORKSPACE = os.path.join(CLIENT_HOME, "workspace")

SERVER_HOME = "carrot-test-frame-auto-perf-track"
SERVER_WORKSPACE = os.path.join("~", SERVER_HOME, "workspace")


class Param:
    action = None
    ip = None
    username = None
    password = None
    project_name = None

    @staticmethod
    def init():
        if len(sys.argv) < 2:
            print("参数错误")
            exit(1)

        Param.action = sys.argv[1]

        argv = sys.argv[2:]
        short_options = 'i:u:w:n:'
        long_options = ['ip=', 'username=', 'password=', 'project_name=']
        opts, args = getopt.getopt(argv, short_options, long_options)
        if len(args) > 1:
            print('unknown param ' + args[0])
            exit(1)
        for opt, arg in opts:
            if opt in ['-i', '--ip']:
                Param.ip = arg
            elif opt in ['-u', '--username']:
                Param.username = arg
            elif opt in ['-w', '--password']:
                Param.password = arg
            elif opt in ['-n', '--project_name']:
                Param.project_name = arg
            else:
                assert False


def log(msg):
    ftime = datetime.now().strftime("%Y-%m-%d %H-%M-%S")
    print(ftime, msg)


def install():
    assert Param.ip is not None and Param.username is not None and Param.password is not None

    log(f"INFO： 检测{Param.username}@{Param.ip}是否安装")
    s, o = subprocess.getstatusoutput(f"sshpass -p {Param.password} ssh {Param.username}@{Param.ip} 'ls | grep {SERVER_HOME} | wc -l'")
    if s != 0:
        log(f"ERROR：无法检测 {Param.username}@{Param.ip} 是否已经安装perftrack")
        exit(1)
    if o != "0":
        log(f"INFO： {Param.username}@{Param.ip} 已经安装 perftrack")
        exit(0)

    log(f"INFO： 安装 perf track 到 {Param.username}@{Param.ip}")

    os.system(f"sshpass -p {Param.password} scp -r {CLIENT_HOME} {Param.username}@{Param.ip}:{SERVER_HOME}")


def run_remote():
    assert Param.ip is not None and Param.username is not None and Param.password is not None and Param.project_name is not None
    log(f"INFO：{Param.username}@{Param.ip} 启动 perf tarck")
    os.system(f"sshpass -p {Param.password} ssh {Param.username}@{Param.ip} 'cd {SERVER_HOME} ; python3 run.py run -n {Param.project_name}' &")


def run():
    assert Param.project_name is not None

    workspace = os.path.join(SERVER_WORKSPACE, Param.project_name)
    if not os.access(workspace, os.F_OK):
        os.system(f"mkdir -p {workspace}")

    import multiprocessing
    def run_process_detach(_worker):
        import multiprocessing
        p = multiprocessing.Process(target=_worker)
        p.daemon = True
        p.start()

    def nmon_worker():
        # RUN nmon
        nmon_res_file = os.path.join(workspace, f"result.nmon")
        cmd = f'cd nmon; ./nmon_arm -c 20000 -s 5 -F {nmon_res_file}; cd ..'
        os.system(cmd)

    def disk_monitor():
        # RUN disk monitor
        disk_res_file = os.path.join(workspace, f"disk.log")
        cmd = f"python3 disk/disk_monitor.py {disk_res_file}"
        # p = subprocess.Popen(cmd, detach=True, shell=True)
        os.system(f"{cmd} &")

    run_process_detach(nmon_worker)
    run_process_detach(disk_monitor)
    
    os.system("echo dsadsa > xxx")
    


def stop_remote():
    assert Param.ip is not None and Param.username is not None and Param.password is not None and Param.project_name is not None

    log(f"INFO: 停止 {Param.username}@{Param.ip} perf tarck")

    cmd = f"sshpass -p {Param.password} ssh {Param.username}@{Param.ip} 'cd {SERVER_HOME} ; python3 run.py stop -n {Param.project_name}'"
    os.system(cmd)


def stop():
    assert Param.project_name is not None
    # Stop nmon
    cmd = f'ps ux | grep 20000 | grep nmon | grep {Param.project_name}'
    s, o = subprocess.getstatusoutput(cmd)
    pid = o.split()[1]
    os.system(f'kill -9 {pid}')

    # stop disk monitor
    cmd = f'ps ux | grep disk_monitor | grep {Param.project_name}'
    s, o = subprocess.getstatusoutput(cmd)
    pid = o.split()[1]
    os.system(f'kill -9 {pid}')


def download_result():
    assert Param.ip is not None and Param.username is not None and Param.password is not None and Param.project_name is not None

    workspace = os.path.join(CLIENT_WORKSPACE, Param.project_name)
    if not os.access(workspace, os.F_OK):
        os.system(f"mkdir -p {workspace}")

    remote_path = os.path.join(SERVER_WORKSPACE, Param.project_name)
    local_path = os.path.join(workspace, f"{Param.username}_{Param.ip}")
    os.system(f"sshpass -p {Param.password} scp -r {Param.username}@{Param.ip}:{remote_path} {local_path}")



if __name__ == '__main__':

    Param.init()

    # 安装所有的工具到远端
    if Param.action in ['install']:
        install()

    # 客户端执行，再被监控端启动运行
    elif Param.action in ['run-remote']:
        run_remote()

    # 被监控端执行，本地运行监控任务
    elif Param.action in ['run']:
        run()

    # 客户端执行，再被监控端停止监控任务
    elif Param.action in ['stop-remote']:
        stop_remote()

    # 被监控端执行，本地停止监控任务
    elif Param.action in ['stop']:
        stop()

    # 客户端执行，从被监控端下载监控结果
    elif Param.action in ['download-result']:
        download_result()

    else:
        print("参数错误")
        exit(1)



